package com.jevons.muffin.utilcode;

import android.os.Build;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * Copyright 2020 JxGIS
 *
 * @file CrashPrintUtils
 * @auth linaisheng
 * Created on 2021/6/30.
 * Description：
 */
public class CrashPrintUtils {

    private static final ExecutorService EXECUTOR = Executors.newSingleThreadExecutor();
    private static final Config CONFIG  = new Config();

    public static Config getConfig() {
        return CONFIG;
    }

    public final static void print2Crash(Throwable throwable) {

        if (CONFIG.isLogSwitch()) {

            if (CONFIG.isLog2FileSwitch()) {
                EXECUTOR.execute(new Runnable() {
                    @Override
                    public void run() {
                        //存储到崩溃日志文件

                        Date d = new Date();
                        String format = new SimpleDateFormat(
                                "yyyy_MM_dd HH:mm:ss.SSS ", Locale.getDefault()).format(d);
                        String date = format.substring(0, 10);

                        final String exceptionPath =
                                CONFIG.getExceptionDir() + getExceptionFileName(date);
                        LogUtils.print2Crash(exceptionPath, throwable);
                        if (CONFIG.exceptionListener != null) {
                            CONFIG.exceptionListener.handleExceptionSuccess(exceptionPath);
                        }
                    }
                });
            }
            if (CONFIG.isLog2ConsoleSwitch()) {
                //打印到控制台
                LogUtils.eTag("CrashException", throwable);
            }
        }

    }

    static String getExceptionFileName(String date) {
        return Build.MODEL + "_" + date + "_" +
                CONFIG.getProcessName() + CONFIG.getFileExtension();
    }

    public static final class Config {

        private String                  mDefaultExceptionDir;       // The default storage directory of exception log
        private String                  mExceptionDir;              // The storage directory of exception log

        private String                  mFileExtension     = ".txt";// The file extension of log.

        private boolean                 mLogSwitch         = true;  // The switch of log.
        private boolean                 mLog2ConsoleSwitch = true;  // The logcat's switch of log.
        private boolean                 mLog2FileSwitch    = true; // The file's switch of log.

        private String                  mProcessName       = UtilsBridge.getCurrentProcessName();

        private HandleExceptionListener exceptionListener;

        private Config() {
            if (UtilsBridge.isSDCardEnableByEnvironment()
                    && Utils.getApp().getExternalFilesDir(null) != null) {
                mDefaultExceptionDir = Utils.getApp().getExternalCacheDir()
                        + LogUtils.FILE_SEP + "exceptionLog" + LogUtils.FILE_SEP;
            } else {
                mDefaultExceptionDir = Utils.getApp().getExternalCacheDir()
                        + LogUtils.FILE_SEP + "exceptionLog" + LogUtils.FILE_SEP;
            }
        }

        public final Config setLogSwitch(final boolean logSwitch) {
            mLogSwitch = logSwitch;
            return this;
        }

        public final Config setConsoleSwitch(final boolean consoleSwitch) {
            mLog2ConsoleSwitch = consoleSwitch;
            return this;
        }


        public final Config setLog2FileSwitch(final boolean log2FileSwitch) {
            mLog2FileSwitch = log2FileSwitch;
            return this;
        }

        public final Config setExceptionDir(final String dir) {
            if (UtilsBridge.isSpace(dir)) {
                mExceptionDir = null;
            } else {
                mExceptionDir = dir.endsWith(LogUtils.FILE_SEP) ? dir : dir + LogUtils.FILE_SEP;
            }
            return this;
        }

        public final Config setExceptionDir(final File dir) {
            mExceptionDir = dir == null ? null : (dir.getAbsolutePath() + LogUtils.FILE_SEP);
            return this;
        }

        //崩溃日志文件目录
        private final String getExceptionDir() {
            return mExceptionDir == null ? mDefaultExceptionDir : mExceptionDir;
        }

        public final Config setFileExtension(final String fileExtension) {
            if (UtilsBridge.isSpace(fileExtension)) {
                mFileExtension = ".txt";
            } else {
                if (fileExtension.startsWith(".")) {
                    mFileExtension = fileExtension;
                } else {
                    mFileExtension = "." + fileExtension;
                }
            }
            return this;
        }

        private String getProcessName() {
            if (mProcessName == null) return "";
            return mProcessName.replace(":", "_");
        }

        private String getFileExtension() {
            return mFileExtension;
        }

        private boolean isLogSwitch() {
            return mLogSwitch;
        }

        private boolean isLog2ConsoleSwitch() {
            return mLog2ConsoleSwitch;
        }

        private boolean isLog2FileSwitch() {
            return mLog2FileSwitch;
        }

        public void setExceptionListener(HandleExceptionListener exceptionListener) {
            this.exceptionListener = exceptionListener;
        }

        @Override
        public String toString() {
            return "process: " + getProcessName()
                    + LogUtils.LINE_SEP + "logSwitch: " + isLogSwitch()
                    + LogUtils.LINE_SEP + "consoleSwitch: " + isLog2ConsoleSwitch()
                    + LogUtils.LINE_SEP + "fileSwitch: " + isLog2FileSwitch()
                    + LogUtils.LINE_SEP + "exceptionDir: " + getExceptionDir();
        }
    }

    public interface HandleExceptionListener {

        void handleExceptionSuccess(String fullPath);

    }

}
